const brush = require("chalk-animation");
/**
 * @description 龟兔赛跑模块
 * */
class Race {
  /**
   * @description 兔子
   * */
  rabbit = "兔子";
  /**
   * @description 乌龟
   * */
  tortoies = "乌龟";
  /**
   * @description 兔子跑的步数
   * */
  rabbitStep = 0;
  /**
   * @description 乌龟跑的步数
   * */
  tortoiesStep = 0;
  /**
   * @description 赛道总长
   * */
  totalStep = 50;
  /**
   * @description 兔子停下来的步数
   * */
  stopStep = Math.floor(Math.random() * (40 - 20 + 1) + 20);
  /**
   * @description 赛道开始图标
   * */
  start = "|";
  /**
   * @description 赛道结束图标
   * */
  end = "》";
  /**
   * @description 赛道样式
   * */
  raceStyle = ".";
  /**
   * @description 定时器ID
   * */
  timer = null;
  /**
   * @description 轮训次数
   * */
  trainNumber = 0;
  /**
   * @description 绘制屏幕
   * @param content 内容
   * */
  draw(content) {
    this.replaceBrush.replace(content);
  }
  /**
   * @description 初次绘制
   * @param  brush {{rainbow:Function}}画笔
   * @param content 内容
   * */
  initDraw(brush, content) {
    return brush.rainbow(content);
  }
  /**
   * @description 初始化屏幕内容
   * @return
   * */
  initContent() {
    return (
      this.rabbit +
      this.tortoies +
      this.start +
      this.raceStyle.repeat(this.totalStep) +
      this.end
    );
  }
  /**
   * @description 更新状态
   * */
  updateState() {
    ++this.trainNumber;
    this.rabbitStep =
      this.rabbitStep + this.trainNumber * 3 >= this.stopStep
        ? this.stopStep
        : this.rabbitStep + this.trainNumber * 3;
    this.tortoiesStep =
      this.tortoiesStep + this.trainNumber >= this.totalStep
        ? this.totalStep
        : this.tortoiesStep + this.trainNumber;
    if (this.tortoiesStep >= this.totalStep) {
      clearInterval(this.timer);
    }
  }
  /**
   * @description  重绘窗口
   * */
  repaint(brush) {
    const [[minAnimal, minStep], [maxAnimal, maxStep]] = [
      [this.rabbit, this.rabbitStep],
      [this.tortoies, this.tortoiesStep],
    ].sort((animalInfo, otherAnimalInfo) => animalInfo[1] - otherAnimalInfo[1]);
    if (!this.rabbitStep && !this.tortoies) {
      this.draw(brush, this.initContent());
    }
    const startInfo =
      this.start + this.raceStyle.repeat(minStep - 1) + minAnimal;
    const middleRaceStyle = this.raceStyle.repeat(maxStep - minStep);
    const endInfo =
      maxStep >= this.totalStep
        ? this.end + maxAnimal
        : maxAnimal +
          this.raceStyle.repeat(this.totalStep - maxStep) +
          this.end;
    this.draw(brush, startInfo + middleRaceStyle + endInfo);
  }
  /**
   * @description 开跑
   * */
  async race() {
    const initContent = this.initContent();
    this.replaceBrush = this.initDraw(brush, initContent);
    await new Promise((resolve) =>
      setTimeout(() => {
        resolve();
      }, 500)
    );
    this.timer = setInterval(() => {
      this.updateState();
      this.repaint(brush);
    }, 500);
  }
}
new Race().race();
